package com.loe.ktui

import android.annotation.SuppressLint
import android.content.Context
import android.content.res.ColorStateList
import android.content.res.TypedArray
import android.graphics.Paint
import android.graphics.Typeface
import android.text.TextUtils.TruncateAt
import android.util.AttributeSet
import android.util.TypedValue
import android.view.ViewGroup
import android.widget.Button
import androidx.core.content.res.getBooleanOrThrow
import androidx.core.content.res.getDimensionOrThrow
import androidx.core.content.res.getStringOrThrow
import androidx.core.view.isVisible
import com.loe.ktui.util.KtColor
import com.loe.ktui.util.KtCornerProvider

open class UiButton(id: String? = null) : UiView(id)
{
    var text: CharSequence? = null
    var textColor: Int? = null
    var autoText: CharSequence? = null
    var hint: String? = null
    var hintColor: Int? = null
    var gravity: Int? = null
    var isTextSelectable: Boolean? = null
    var minLines: Int? = null
    var maxLines: Int? = null
    var ellipsis: TruncateAt? = null
    var bold: Boolean? = null
    var italic: Boolean? = null
    var textStyle: String? = null
    var textSize: Any? = null
    var isAutoVisible: Boolean? = null

    open var isAlphaTextClick: Boolean? = null

    var onText: (KtButton.(s: String) -> Unit)? = null
    fun onText(onText: KtButton.(s: String) -> Unit)
    {
        this.onText = onText
    }

    open fun initUI(context: Context, view: KtButton)
    {
        super.initUI(context, view)

        isAlphaClick?.let { view.isAlphaClick = it }
        isAlphaTextClick?.let { view.isAlphaTextClick = it }

        isAutoVisible?.let { view.isAutoVisible = it }
        text?.let { view.text = it }
        autoText?.let { view.autoText = it }
        view.setTextColor(textColor ?: KtColor.text)
        hint?.let { view.hint = it }
        hintColor?.let { view.setHintTextColor(it) }
        gravity?.let { view.gravity = it }
        isTextSelectable?.let { view.setTextIsSelectable(it) }
        minLines?.let { view.minLines = it }
        maxLines?.let { view.maxLines = it }
        ellipsis?.let { view.ellipsize = it }
        bold?.let { view.setBold(it) }
        italic?.let { view.setItalic(it) }
        textStyle?.let { view.setTextStyle(it) }
        hintColor?.let { view.setHintTextColor(it) }
        textSize?.let { view.setTextSize(TypedValue.COMPLEX_UNIT_PX, it.distFloat) }

        onText?.let { onText -> view.setTextListener{ view.onText(it) } }
    }

    /** 创建view */
    override fun createView(context: Context, parent: ViewGroup?): KtButton
    {
        return KtButton(context).also()
        {
            initUI(context, it)
            addToParent(parent, it)
        }
    }
}

fun Any.ui_Button(id: String? = null, block: (UiButton.() -> Unit)? = null): UiButton
{
    val ui = UiButton(id)
    block?.let { ui.it() }
    if (this is UiGroup) addChild(ui)
    return ui
}

@SuppressLint("AppCompatCustomView")
open class KtButton : Button
{
    constructor(context: Context) : super(context)
    {
        initXML()
    }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
    {
        initXML(context.obtainStyledAttributes(attrs, R.styleable.KtButton))
    }

    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
    {
        initXML(context.obtainStyledAttributes(attrs, R.styleable.KtButton, defStyleAttr, 0))
    }

    var status = 0

    private fun initXML(typedArray: TypedArray? = null)
    {
        typedArray?.let()
        {
            if (it.hasValue(R.styleable.KtButton_kt_corner))
            {
                val corner = it.getDimensionOrThrow(R.styleable.KtButton_kt_corner).toInt()
                val cornerDirect =  KtDirects[it.getInt(R.styleable.KtButton_kt_cornerDirect, 4)]

                outlineProvider = KtCornerProvider(corner, cornerDirect, this)
            }
            if (it.hasValue(R.styleable.KtButton_kt_isAlphaClick))
            {
                isAlphaClick = it.getBooleanOrThrow(R.styleable.KtButton_kt_isAlphaClick)
            }
            if (it.hasValue(R.styleable.KtButton_kt_isAlphaTextClick))
            {
                isAlphaTextClick = it.getBooleanOrThrow(R.styleable.KtButton_kt_isAlphaTextClick)
                setTextColor(currentTextColor)
            }
            if (it.hasValue(R.styleable.KtButton_kt_link))
            {
                link = it.getStringOrThrow(R.styleable.KtButton_kt_link)
            }

            if (it.hasValue(R.styleable.KtButton_kt_isAutoVisible))
            {
                isAutoVisible = it.getBooleanOrThrow(R.styleable.KtButton_kt_isAutoVisible)
            }
            if (it.hasValue(R.styleable.KtButton_kt_autoText))
            {
                isAutoVisible = true
                autoText = it.getStringOrThrow(R.styleable.KtButton_kt_autoText)
            }

            it.recycle()
        }
    }

    /******************************************* 其他 *******************************************/

    var link = ""
        set(value)
        {
            field = value
            setKtDelayClickListener { KtUi.onLink?.invoke(context, value) }
        }

    var isAutoVisible: Boolean = false

    var autoText: CharSequence?
        get() = text
        set(value)
        {
            if (isAutoVisible) isVisible = value != null && value.trim().isNotEmpty()
            text = value
        }

    var isAlphaClick = false
        set(value)
        {
            field = value
            isClickable = value
        }

    override fun dispatchSetPressed(pressed: Boolean)
    {
        if (isAlphaClick) alpha = if (pressed || !isEnabled) 0.75f else 1f
        super.dispatchSetPressed(pressed)
    }

    override fun setEnabled(enabled: Boolean)
    {
        if (isAlphaClick) alpha = if (enabled) 1f else 0.75f
        super.setEnabled(enabled)
    }

    var isAlphaTextClick = false
        set(value)
        {
            field = value
            isClickable = value
        }

    override fun setTextColor(color: Int)
    {
        if (isAlphaTextClick)
        {
            val states = arrayOfNulls<IntArray>(3)
            states[0] = intArrayOf(android.R.attr.state_enabled, -android.R.attr.state_pressed)
            states[1] = intArrayOf(android.R.attr.state_enabled, android.R.attr.state_pressed)
            states[2] = intArrayOf(-android.R.attr.state_enabled)
            val alphaColor = (0xaa shl 24) + (color and 0xFFFFFF)
            setTextColor(ColorStateList(states, intArrayOf(color, alphaColor, alphaColor)))
        } else
        {
            super.setTextColor(color)
        }
    }

    private var onText: ((s: String) -> Unit)? = null

    private val addTextChanged by lazy {
        addKtTextAfterListener()
        {
            onText?.invoke(it)
        }
    }

    fun setTextListener(onText: (s: String) -> Unit)
    {
        this.onText = onText
        addTextChanged
    }

    /***************************************** 文本样式 ***************************************/

    fun setBold(bold: Boolean)
    {
        typeface = if (bold) Typeface.DEFAULT_BOLD else Typeface.DEFAULT
    }

    fun setItalic(italic: Boolean)
    {
        setTypeface(Typeface.DEFAULT, if (italic) Typeface.ITALIC else Typeface.NORMAL)
    }

    fun setTextStyle(textStyle: String)
    {
        when (textStyle)
        {
            "bold" -> paint.flags = Paint.FAKE_BOLD_TEXT_FLAG or Paint.ANTI_ALIAS_FLAG
            "delete" -> paint.flags = Paint.STRIKE_THRU_TEXT_FLAG or Paint.ANTI_ALIAS_FLAG
            "under" -> paint.flags = Paint.UNDERLINE_TEXT_FLAG or Paint.ANTI_ALIAS_FLAG
            // normal
            else -> paint.flags = Paint.ANTI_ALIAS_FLAG
        }
    }

    fun setTextSize(size: Any)
    {
        if (size is Double)
        {
            setTextSize(TypedValue.COMPLEX_UNIT_DIP, size.toFloat())
        } else
        {
            setTextSize(TypedValue.COMPLEX_UNIT_PX, size.toString().toFloat())
        }
    }
}